package com.springcloud.consumer02.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSONObject;
import com.springcloud.consumer02.blockhandler.UserBlockHandler;
import com.springcloud.consumer02.blockhandler.UserFallback;
import com.springcloud.consumer02.dto.UserInfo;
import com.springcloud.consumer02.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/info")
    public JSONObject getUserInfo(String username) {
        JSONObject info = userService.getUserInfo(username);
        return info;
    }


    /**
     * SentinelResource:处理sentinel异常
     * 参数：
     * value：资源名，不能为空，可以是url路径，也可以是自定义资源名，尽量使用自定义资源名
     * blockHandler：处理BlockException的方法，要求：
     * 1.访问修饰符必须是public
     * 2.数据返回类型要和原方法的一致
     * 3.方法参数数据类型和原方法一致，并且额外添加一个BlockException参数
     * 4.方法要和原方法在同一个类中
     * blockHandlerClass：允许blockHandler方法统一放在一个类中，该类中的handler方法必须是static修饰
     * blockHandlerClass和blockHandler组合使用，blockHandlerClass指定处理类，blockHandler指定类中的处理方法
     * <p>
     * fallback：处理异常的方法，要求：
     * 1.访问修饰符必须是public
     * 2.返回数据类型和原方法一致
     * 3.方法参数数据类型和原方法一致，并且额外添加Throwable参数
     * 4.方法要和原方法在同一个类中
     * fallbackClass：允许fallback方法统一放在一个类中，该类中的fallback方法必须是static修饰
     * fallbackClass和fallback组合使用，fallbackClass指定处理类，fallback指定类中的处理方法
     *
     * sentinel和openfeign整合：
     * 需要在application.properties文件中添加:feign.sentinel.enabled=true，开启openfeign和sentinel熔断
     *
     * feign主要监控远程接口调用出现的异常，进行降级处理
     * sentinel主要监控本地方法出现的异常，进行降级处理
     * 如果远程接口和本地方法都出现异常，则最终由sentinel处理
     *
     * @param username
     * @param password
     * @return
     */
    @SentinelResource(value = "addUser", blockHandlerClass = UserBlockHandler.class, blockHandler = "addUserHandler", fallbackClass = UserFallback.class, fallback = "addUserFallback")
    @GetMapping("/add")
    public JSONObject addUserInfo(String username, String password) {


        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(username);
        userInfo.setPassword(password);
        JSONObject info = userService.addUserInfo(userInfo);

        int i = 1 / 0;

        return info;
    }

}
